#!/bin/bash
set -e

# ---------------------------
# 强制切换到指定目录
# ---------------------------
CUR_DIR="${PWD}"
BASE_DIR="${PWD}/The-Art-of-Writing-Efficient-Programs/Chapter04"
cd "$BASE_DIR" || { echo "Directory $BASE_DIR not found"; exit 1; }

# ---------------------------
# 配置变量
# ---------------------------
MAIN_PROF_FILE="prof.data"
LIB_PROFILER="/usr/local/lib/libprofiler.so.0"
PROF_FREQ=1000

# ---------------------------
# 函数定义
# ---------------------------

# 编译程序（可变源文件参数，如果没有源文件则跳过编译）
# 用法: compile_program out_name src1 src2 ...
compile_program() {
    local out="$1"
    shift
    local srcs=("$@")

    if [ ${#srcs[@]} -eq 0 ]; then
        echo "No source files provided, skipping compilation."
        return
    fi

    # -fno-omit-frame-pointer -fno-pie -no-pie \
    echo "Compiling ${srcs[*]} -> $out ..."
    clang++ "${srcs[@]}" \
        -g -O3 \
        -I. --std=c++17 \
        -lprofiler \
        -lbenchmark -lpthread \
        -o "$out"
    echo "Compilation finished: $out"
}

# 运行程序并收集 profiler 数据
run_profiler() {
    local out="$1"

    echo "Running $out with gperftools CPU profiler..."
    LD_PRELOAD="$LIB_PROFILER" \
    CPUPROFILE="$MAIN_PROF_FILE" \
    CPUPROFILE_FREQUENCY="$PROF_FREQ" \
    "./$out"
    echo "Profiler data saved to $MAIN_PROF_FILE"
}

# 使用 Google pprof 分析
analyze_profile() {
    local out="$1"
    echo "perf record ..."
    perf record "./$out"
    perf report

    echo "Generate Google pprof pdf..."
    google-pprof --pdf "./$out" "$MAIN_PROF_FILE" > prof.pdf
    echo "Launching Google pprof..."
    google-pprof "./$out" "$MAIN_PROF_FILE"
}

# ---------------------------
# main 函数，接收参数
# ---------------------------
# 用法: main out_name src1 src2 ...
main() {
    local out="$1"
    shift
    local srcs=("$@")

    local run_profile=false
    if [ "${srcs[-1]}" = "true" ]; then
        run_profile=true
        unset 'srcs[-1]'  # 去掉最后一个参数（避免被当作源文件）
    fi

    compile_program "$out" "${srcs[@]}"

    if [ "$run_profile" = true ]; then
        run_profiler "$out"
        analyze_profile "$out"
    else
        echo "⚙️  仅编译完成，跳过性能测试。"
    fi
}

# ---------------------------
# 调用 main，参数从命令行传入
# ---------------------------
# 默认参数
MAIN_SRCS=("$@")
first_src="${MAIN_SRCS[0]}"
base_name="$(basename "$first_src" | sed 's/\.[^.]*$//')"  # 去掉扩展名
MAIN_OUT="${CUR_DIR}/${base_name}.out"

main "$MAIN_OUT" "${MAIN_SRCS[@]}"

# clang++ 02_branch.C -g -O3 -mavx2 --std=c++17 -mllvm -x86-asm-syntax=intel -S -o - | llvm-mca -mcpu=btver2 -timeline
